package org.grid.maingui;

import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.table.DefaultTableModel;
import org.grid.gui.MessageBox;
import org.grid.gui.TextMessageBox;
import org.grid.model.*;
import org.grid.model.logic.LogProcessor;
import org.grid.model.reader.LogReader;
import org.grid.model.rmi.*;

/**
 *
 * @author wellington
 */
public class JFrmProcess extends javax.swing.JInternalFrame {

    private NodeManager nodeManager;
    // <editor-fold defaultstate="collapsed" desc="Singleton">
    private static JFrmProcess instance;
    private static final long serialVersionUID = 6606473346101810834L;

    public static JFrmProcess getInstance(JDesktopPane owner) {
        if (instance == null) {
            instance = new JFrmProcess();
        }
        owner.add(instance);
        instance.setVisible(true);
        owner.getDesktopManager().activateFrame(instance);
        return instance;
    }

    public static JFrmProcess getInstance() {
        if (instance == null) {
            instance = new JFrmProcess();
        }
        return instance;
    }
    LogProcessor logProcessator;

    private JFrmProcess() {
        initComponents();
        loadNodes();
    }
    // </editor-fold>

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        chooserLog = new javax.swing.JFileChooser();
        pnlLoad = new javax.swing.JPanel();
        txtLoadPath = new javax.swing.JTextField();
        btnLoad = new javax.swing.JButton();
        lblLoadPath = new javax.swing.JLabel();
        pnlNodes = new javax.swing.JPanel();
        pnlScrollNodes = new javax.swing.JScrollPane();
        tblNodes = new javax.swing.JTable();
        lblLoad = new javax.swing.JLabel();
        btnRefresh = new javax.swing.JButton();
        prgProcess = new javax.swing.JProgressBar();
        pnlBottom = new javax.swing.JPanel();
        btnProcess = new javax.swing.JButton();

        chooserLog.setApproveButtonToolTipText("Selecionar o arquivo de log");
        chooserLog.setBackground(java.awt.Color.white);
        chooserLog.setDialogTitle("Caminho do arquivo de log");
        chooserLog.setFileHidingEnabled(true);
        chooserLog.setRequestFocusEnabled(false);

        setClosable(true);
        setResizable(true);
        setTitle("Processar");
        setFrameIcon(new javax.swing.ImageIcon(getClass().getResource("/org/grid/maingui/main.png"))); // NOI18N

        pnlLoad.setBorder(javax.swing.BorderFactory.createTitledBorder("Carregar LOG"));
        pnlLoad.setLayout(new java.awt.GridBagLayout());

        txtLoadPath.setEditable(false);
        txtLoadPath.setToolTipText("caminho do arquivo de log");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        pnlLoad.add(txtLoadPath, gridBagConstraints);

        btnLoad.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/grid/resources/folder.png"))); // NOI18N
        btnLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        pnlLoad.add(btnLoad, gridBagConstraints);

        lblLoadPath.setText("Caminho do arquivo de log");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        pnlLoad.add(lblLoadPath, gridBagConstraints);

        getContentPane().add(pnlLoad, java.awt.BorderLayout.PAGE_START);

        pnlNodes.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pnlNodes.setLayout(new java.awt.GridBagLayout());

        tblNodes.setShowVerticalLines(false);
        pnlScrollNodes.setViewportView(tblNodes);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlNodes.add(pnlScrollNodes, gridBagConstraints);

        lblLoad.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/grid/resources/loader.gif"))); // NOI18N
        lblLoad.setText("Carregando");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlNodes.add(lblLoad, gridBagConstraints);
        lblLoad.setVisible(false);

        btnRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/grid/resources/refresh.png"))); // NOI18N
        btnRefresh.setText("Atualizar");
        btnRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRefreshActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlNodes.add(btnRefresh, gridBagConstraints);

        prgProcess.setForeground(new java.awt.Color(0, 51, 153));
        prgProcess.setToolTipText("Aguarde...");
        prgProcess.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        prgProcess.setIndeterminate(true);
        prgProcess.setString("Processando Log, Aguarde");
        prgProcess.setStringPainted(true);
        prgProcess.setVisible(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        pnlNodes.add(prgProcess, gridBagConstraints);

        getContentPane().add(pnlNodes, java.awt.BorderLayout.CENTER);

        pnlBottom.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        btnProcess.setText("Processar");
        btnProcess.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnProcessActionPerformed(evt);
            }
        });
        pnlBottom.add(btnProcess);

        getContentPane().add(pnlBottom, java.awt.BorderLayout.SOUTH);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-593)/2, (screenSize.height-427)/2, 593, 427);
    }// </editor-fold>//GEN-END:initComponents

    private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed
        Runnable r = new Runnable() {

            public void run() {
                loadLog();
            }
        };
        Thread t = new Thread(r);
        t.start();
}//GEN-LAST:event_btnLoadActionPerformed

    private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
        refreshNodes();
    }//GEN-LAST:event_btnRefreshActionPerformed

    private void btnProcessActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnProcessActionPerformed
        Runnable r = new Runnable() {

            public void run() {
                process();
            }
        };
        Thread t = new Thread(r);
        t.start();
    }//GEN-LAST:event_btnProcessActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnLoad;
    private javax.swing.JButton btnProcess;
    private javax.swing.JButton btnRefresh;
    private javax.swing.JFileChooser chooserLog;
    private javax.swing.JLabel lblLoad;
    private javax.swing.JLabel lblLoadPath;
    private javax.swing.JPanel pnlBottom;
    private javax.swing.JPanel pnlLoad;
    private javax.swing.JPanel pnlNodes;
    private javax.swing.JScrollPane pnlScrollNodes;
    private javax.swing.JProgressBar prgProcess;
    private javax.swing.JTable tblNodes;
    private javax.swing.JTextField txtLoadPath;
    // End of variables declaration//GEN-END:variables

    private void loadLog() {
        if (chooserLog.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) {
            return;
        }
        txtLoadPath.setText(chooserLog.getSelectedFile().getAbsolutePath());
    }

    private void process() {
        btnRefresh.setVisible(false);
        btnLoad.setVisible(false);
        prgProcess.setVisible(true);
        btnProcess.setEnabled(false);
        try {
            long start = System.currentTimeMillis();
            System.out.println(start);
            logProcessator = new LogProcessor(txtLoadPath.getText(), NodeManager.DEFAULT_FILENAME);
            List<Double> lst = logProcessator.startProcess(true);
            long time = System.currentTimeMillis() - start;
            System.out.println(time);
            TextMessageBox.showError(null, "Processamento concluído", String.format("Tempo de resposta: %d ms\nTotal de linhas:%s", time, (lst != null) ? lst.size() : 0));
        } catch (Exception ex) {
            MessageBox.showError(this, ex.getMessage());
        }
        btnProcess.setEnabled(true);
        btnRefresh.setVisible(true);
        btnLoad.setVisible(true);
        prgProcess.setVisible(false);
    }

    private void loadNodes() {
        if (nodeManager == null) {
            nodeManager = new NodeManager();
        }
        nodeManager.load();
        List<Node> nodes = nodeManager.list();
        String[] headers = new String[]{"Nó", "Endereço", "Situação", "Resposta (ms)"};
        String[][] data = new String[nodes.size()][headers.length];
        for (int i = 0; i < nodes.size(); i++) {
            data[i][0] = nodes.get(i).getDescription();
            data[i][1] = nodes.get(i).getAddress() + ":" + nodes.get(i).getPort();
            data[i][2] = "...";
            data[i][3] = "...";
        }
        tblNodes.setModel(new DefaultTableModel(data, headers));
    }

    private void refreshNodes() {
        loadNodes();
        Runnable r = new Runnable() {

            public void run() {
                testNodes();
            }
        };
        Thread t = new Thread(r);
        t.setPriority(Thread.MAX_PRIORITY);
        t.start();
    }

    private void testNodes() {
        btnRefresh.setEnabled(false);
        lblLoad.setVisible(true);
        List<Node> nodes = nodeManager.list();
        for (int i = 0; i < nodes.size(); i++) {
            tblNodes.getModel().setValueAt("Testando...", i, 2);
            LogCalculator lc = nodes.get(i).getLogCalculator(true);
            if (lc != null) {
                try {
                    tblNodes.getModel().setValueAt((lc.isWorking() ? "Ocupado" : "Disponível"), i, 2);
                    long response = lc.testResponseTime(LoadTest.DEFAULT_LOAD_TEST);
                    tblNodes.getModel().setValueAt(response, i, 3);
                } catch (RemoteException ex) {
                    tblNodes.getModel().setValueAt("Erro", i, 2);
                    tblNodes.getModel().setValueAt("Erro", i, 3);
                }
            } else {
                tblNodes.getModel().setValueAt("Indisponível", i, 2);
                tblNodes.getModel().setValueAt("...", i, 3);
            }
        }
        btnRefresh.setEnabled(true);
        lblLoad.setVisible(false);
    }
}
